package com.example.zzx.dovebook.base;

import android.content.Intent;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import androidx.lifecycle.ViewModelProviders;
import butterknife.ButterKnife;
import com.example.baselibrary.commonutil.DensityModifier;
import com.example.baselibrary.commonutil.Logger;
import com.example.baselibrary.commonutil.ToastUtil;
import com.example.baselibrary.permission.PermissionManager;
import com.example.zzx.dovebook.login.LoginManager;

import java.lang.reflect.Field;

public abstract class BaseActivity<VM extends BaseViewModel> extends AppCompatActivity {

    protected static final int STATUS_BAR_NORMAL = 0;
    protected static final int STATUS_BAR_TRANSPARENT = 1;
    protected static final int STATUS_BAR_LIGHT = 2;

    protected String TAG = getClass().getSimpleName();

    private static final int mDefaultScreenLength  = 384;
    private VM mViewModel;

    private Handler mMainHandler;

    private Fragment lastSelectedFragment;

    @Override
    protected void onStart() {
        super.onStart();
        Logger.e(TAG, "onStart ");
    }

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        Logger.e(TAG, "onCreate ");
        setStatusBar(getStatusBarColor());
        super.onCreate(savedInstanceState);
        setupViewModel();

        mMainHandler = new Handler();

        DensityModifier.setDensity(this, getApplication(), getStandardScreenWidth());
        setContentView(getLayoutId());

        ButterKnife.bind(this);

        LoginManager.getInstance().init(this);
        PermissionManager.getInstance().init(this);

        initIntent(savedInstanceState);

        initViews(savedInstanceState);

        initOptions(savedInstanceState);

        if (getViewModel() != null) {
            setupErrorMessageToast();
            setupMessageToast();
        }
    }



    protected void setupMessageToast() {
        getViewModel().getMessage().observe(this, (message) -> {
            Log.e(TAG, "setupMessageToast: " + message);
            ToastUtil.shortToast(this, (String) message);
        });
    }

    private void setupErrorMessageToast() {
        getViewModel().getErrorMessage().observe(this, (errorMessage) -> {
            Log.e(TAG, "setupErrorMessageToast: " + errorMessage);
            ToastUtil.shortToast(this, (String) errorMessage);
        });
    }

    /**
     * 进行一些初始化的数据设置，例如网络请求，数据的配置等等
     * @param savedInstanceState
     */
    protected void initOptions(Bundle savedInstanceState) {

    }

    /**
     * 设置透明状态栏
     * @param type {@link #STATUS_BAR_TRANSPARENT},
     * {@link #STATUS_BAR_LIGHT},{@link #STATUS_BAR_NORMAL}
     */
    protected void setStatusBar(int type) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
            return ;
        }
        Window window = getWindow();
        switch (type) {
            case STATUS_BAR_TRANSPARENT:
                window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
                window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
                break;
            case STATUS_BAR_LIGHT:
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                    window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
                    window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR |
                            View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
                }
                break;
            case STATUS_BAR_NORMAL:
                return ;
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            try {
                Class decorClazz = getClassLoader().loadClass("com.android.internal.policy.DecorView");
                Field field = decorClazz.getDeclaredField("mSemiTransparentStatusBarColor");
                if (!field.isAccessible()) {
                    field.setAccessible(true);
                }
                field.set(getWindow().getDecorView(), Color.TRANSPARENT);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (NoSuchFieldException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        window.addFlags(Window.FEATURE_NO_TITLE);
    }

    /**
     * 返回状态栏的透明类型
     * @return
     */
    protected int getStatusBarColor() {
        return STATUS_BAR_LIGHT;
    }

    /**
     * 初始化其他页面传过来的Intent
     * @param savedInstanceState
     */
    protected void initIntent(Bundle savedInstanceState) {

    }

    /**
     * 初始化各种View
     * @param savedInstanceState
     */
    protected void initViews(Bundle savedInstanceState) {

    }

    /**
     * 屏幕适配中所参考的设计图中的屏幕宽度dp
     * @return
     */
    protected int getStandardScreenWidth() {
        return mDefaultScreenLength;
    }

    /**
     * @return 返回布局id
     */
    protected abstract int getLayoutId();

    /**
     * 创建ViewModel
     */
    private void setupViewModel() {
        Class<VM> vmClazz = createViewModel();
        if (vmClazz == null) {
            return ;
        }
        mViewModel = ViewModelProviders.of(this, new ViewModelFactory(createRepository())).get(vmClazz);
    }

    /**
     * @return 返回与本页面匹配的ViewModel Class
     */
    protected abstract Class<VM> createViewModel();

    /**
     * 返回ViewModel对应的Reponsity
     * @return
     */
    protected Object createRepository() {
        return null;
    }

    public VM getViewModel() {
        if (mViewModel == null) {
            Logger.e(TAG, "view model is null");
            return null;
        }
        return mViewModel;
    }

    protected Handler getMainHandler() {
        return mMainHandler;
    }


    @Override
    protected void onPause() {
        super.onPause();
        Logger.e(TAG, "onPause ");
    }

    @Override
    protected void onStop() {
        super.onStop();
        Logger.e(TAG, "onStop ");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        LoginManager.getInstance().releaseContext(this);
        PermissionManager.getInstance().releaseContext(this);
        Logger.e(TAG, "onDestroy ");
    }

    @Override
    protected void onRestart() {
        super.onRestart();
        Logger.e(TAG, "onRestart ");
    }

    @Override
    protected void onResume() {
        super.onResume();
        Logger.e(TAG, "onResume ");
        LoginManager.getInstance().init(this);
        PermissionManager.getInstance().init(this);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        if (requestCode == LoginManager.REQUEST_CODE && resultCode == RESULT_OK) {
//            UserManager.getInstance(this).updateBuffer();
            LoginManager.getInstance().handleResult(data);
        } else {
            super.onActivityResult(requestCode, resultCode, data);
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        if (PermissionManager.getInstance().handleResult(requestCode, permissions, grantResults)) {
            return;
        }
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }

    protected void replaceFragment(Fragment fragment, int containerId) {
        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction transaction = fragmentManager.beginTransaction();
        if (lastSelectedFragment != null) {
            transaction.hide(lastSelectedFragment);
        }
        if (fragmentManager.findFragmentByTag(fragment.getClass().getSimpleName()) == null) {
            transaction.add(containerId, fragment, fragment.getClass().getSimpleName());
        }
        transaction.show(fragment);
        transaction.commit();
        lastSelectedFragment = fragment;
    }
}
